<!-- pages/post/list.vue -->
<route lang="json5">
{
  style: {
    navigationBarTitleText: '帖子',
    navigationStyle: 'custom'
  }
}
</route>
<template>
  <view class="page">
    <view class="fab" @click="goCreate">
      <text class="icon">+</text>
    </view>
    <!-- <fg-navbar>帖子</fg-navbar> -->

    <!-- 搜索 + 筛选 -->
    <view class="topbar">
      <view class="search">
        <input
          v-model="keyword"
          class="search-input"
          type="text"
          placeholder="搜索关键词（标题/内容）"
          @confirm="onSearch"
          confirm-type="search"
        />
        <button class="search-btn" @click="onSearch">搜索</button>
      </view>

      <view class="tabs">
        <view
          v-for="t in tabs"
          :key="t.value"
          class="tab"
          :class="{ active: type === t.value }"
          @click="onChangeType(t.value)"
        >
          {{ t.label }}
        </view>
      </view>
    </view>

    <!-- 列表 -->
    <scroll-view
      class="list"
      scroll-y
      :refresher-enabled="true"
      :refresher-triggered="refresher"
      refresher-background="#f7f8fa"
      @refresherrefresh="onRefresh"
      @scrolltolower="onLoadMore"
    >
      <view v-if="loading && posts.length === 0" class="empty-tip">加载中…</view>
      <view v-else-if="!loading && posts.length === 0" class="empty-tip">暂无数据</view>

      <view v-for="p in posts" :key="p.id" class="card" @click="goDetail(p.id)">
        <image v-if="p.cover" :src="p.cover" class="cover" mode="aspectFill" />
        <view class="meta">
          <view class="title-row">
            <text class="title">{{ p.title }}</text>
            <text class="badge" :class="p.type === 'secondhand' ? 'b-secondhand' : 'b-parttime'">
              {{ p.type === 'secondhand' ? '二手' : '兼职' }}
            </text>
          </view>
          <view class="desc">{{ p.content }}</view>
          <view class="info-row">
            <text class="price" v-if="p.type === 'secondhand' && p.price !== undefined">¥{{ p.price }}</text>
            <text class="wage" v-if="p.type === 'parttime' && p.wage">{{ p.wage }}</text>
            <text class="loc" v-if="p.location">{{ p.location }}</text>
            <text class="time">{{ formatTime(p.uptim) }}</text>
          </view>
        </view>
      </view>

      <view v-if="!loading && hasMore" class="load-more">上拉加载更多</view>
      <!-- <view v-else-if="!loading && posts.length > 0 && !hasMore" class="load-more">没有更多了</view> -->
    </scroll-view>
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { Post, PostType } from '@/mock/api'
import { mockPostSearch } from '@/mock/api'

type TabValue = 'all' | PostType

const tabs = [
  { label: '全部', value: 'all' as TabValue },
  { label: '二手', value: 'secondhand' as TabValue },
  { label: '兼职', value: 'parttime' as TabValue },
  { label: '交友', value: 'friendship' as TabValue }
]

const keyword = ref('')
const type = ref<TabValue>('all')

const posts = ref<Post[]>([])
const page = ref(1)
const pageSize = 10
const hasMore = ref(true)
const loading = ref(false)
const refresher = ref(false)

onMounted(() => {
  load(true)
})

function formatTime(ts: number) {
  const d = new Date(ts)
  const pad = (n: number) => String(n).padStart(2, '0')
  return `${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
}

async function load(reset = false) {
  if (loading.value) return
  loading.value = true
  try {
    if (reset) {
      page.value = 1
      posts.value = []
      hasMore.value = true
    }
    const { list, hasMore: more } = await mockPostSearch({
      keyword: keyword.value,
      type: type.value,
      page: page.value,
      pageSize
    })
    posts.value = reset ? list : posts.value.concat(list)
    hasMore.value = more
    if (more) page.value += 1
  } finally {
    loading.value = false
    refresher.value = false
  }
}

function onSearch() {
  load(true)
}

function onChangeType(v: TabValue) {
  if (type.value === v) return
  type.value = v
  load(true)
}

function onRefresh() {
  refresher.value = true
  load(true)
}

function onLoadMore() {
  if (!hasMore.value || loading.value) return
  load(false)
}

function goDetail(id: string) {
  uni.navigateTo({ url: `/pages/post/detail?id=${id}` })
}

function goCreate() {
  uni.navigateTo({ url: '/pages/post/create' })
}
</script>

<style scoped lang="scss">
.page { background: #f7f8fa; }
.topbar { padding: 8px 12px 0 12px; background: #fff; }
.search {
  display: flex;
  align-items: center;    // 垂直居中对齐 input 和 button
  gap: 8px;
}
.search-input {
  flex: 1;
  height: 36px;           // 固定高度，与按钮匹配
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 8px 10px;
  font-size: 14px;
  line-height: 1;
}
.search-btn {
  width: 80px;            // 调宽按钮（原为自动宽度）
  height: 55px;           // 与输入框一致的高度
  background: #2563eb;
  color: #fff;
  border-radius: 10px;
  font-size: 14px;        // 放大字体，更美观
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;             // 移除默认 padding
}
.tabs { display: flex; gap: 8px; padding: 10px 0 8px; }
.tab { padding: 6px 10px; border-radius: 999px; background: #f3f4f6; font-size: 13px; color: #374151; }
.tab.active { background: #2563eb; color: #fff; }
.list { height: calc(100vh - 166px);}
.card {
  background: #fff; border-radius: 14px; overflow: hidden; margin-bottom: 10px; box-shadow: 0 1px 4px rgba(0,0,0,.04); margin: 10px 12px;
}
.cover { width: 100%; height: 160px; display: block; }
.meta { padding: 10px 12px; }
.title-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.title { font-size: 16px; font-weight: 600; color: #111827; flex: 1; }
.badge { font-size: 12px; padding: 2px 8px; border-radius: 999px; }
.b-secondhand { background: #eef2ff; color: #3730a3; }
.b-parttime  { background: #ecfeff; color: #155e75; }
.desc { color: #4b5563; font-size: 13px; margin-top: 6px; }
.info-row { display: flex; gap: 10px; align-items: center; margin-top: 8px; color: #6b7280; font-size: 12px; }
.price, .wage { font-weight: 600; color: #111827; }
.load-more, .empty-tip { text-align: center; color: #6b7280; padding: 12px 0; }

.fab {
  position: fixed;
  right: 20px;
  bottom: 60px;
  width: 50px;
  height: 50px;
  background: #2563eb;
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4);
  z-index: 999;
  transition: transform 0.1s, background 0.2s;
}

.fab:active {
  transform: scale(0.95);
  background: #1d4ed8;
}

.icon {
  font-size: 28px;
  line-height: 1;
  transform: translateY(-1px); /* 微调居中 */
}
</style>
